﻿using Demo;
using Net.Event;
using Net.Helper;
using System.Diagnostics;
using Cysharp.Threading.Tasks;

namespace DataBaseTest
{
    internal class Program
    {
        static void Main(string[] args)
        {
            NDebug.WriteFileMode = WriteLogMode.All;
            NDebug.BindConsoleLog(false);

            //MySQLHelper.Inject("C:\\Users\\Administrator\\.nuget\\packages\\mysql.data\\9.2.0\\lib\\net8.0\\MySql.Data.dll");
            MySQLHelper.Inject();

            DemoDB.I.BatchSize = 100000;
            DemoDB.I.SqlBatchSize = 1024 * 1024 * 5;
            DemoDB.I.CommandTimeout = 60;
            DemoDB.I.MinUserId = 0;
            DemoDB.I.CheckTables("root");
            DemoDB.I.InitTablesId();
            DemoDB.I.Start();

            //DemoDB.I.Test();

            _ = ConsoleLoop();

            while (true)
            {
                Console.Title = $"查询次数:{DemoDB.I.QueryCount} 提交次数:{DemoDB.I.SubmitCount}";
                Thread.Sleep(100);
            }
        }

        private static async UniTask ConsoleLoop()
        {
            while (true)
            {
                Console.WriteLine("1.输入:add 1000000添加100万个数据");
                Console.WriteLine("2.输入:modify 1 1000000 level = 100修改id从1-100万的数据并修改level=100");
                Console.WriteLine("3.输入:query 1 1000000查询id从1-100万的数据");
                Console.WriteLine("4.输入:delete 1 1000000删除id从1-100万的数据");
                Console.WriteLine("5.输入:executeQuery 1 1000000查询id从1-100万的数据");
                var command = Console.ReadLine();
                if (command.StartsWith("add"))
                {
                    var parts = command.Split(" ");
                    await AddDataTest(int.Parse(parts[1]));
                }
                if (command.StartsWith("modify"))
                {
                    var parts = command.Split(" ");
                    await ModifyDataTest(int.Parse(parts[1]), int.Parse(parts[2]), parts[3], parts[5]);
                }
                if (command.StartsWith("query"))
                {
                    var parts = command.Split(" ");
                    await QueryDataTest(int.Parse(parts[1]), int.Parse(parts[2]));
                }
                if (command.StartsWith("executeQuery"))
                {
                    var parts = command.Split(" ");
                    await TestExecuteQuery(int.Parse(parts[1]), int.Parse(parts[2]));
                }
                if (command.StartsWith("delete"))
                {
                    var parts = command.Split(" ");
                    await DeleteDataTest(int.Parse(parts[1]), int.Parse(parts[2]));
                }
                if (command == "save")
                {
                    DemoDB.I.WaitBatchWorker();
                }
            }
        }

        private static async UniTask TestExecuteQuery(int id, int count)
        {
            var stopwatch = Stopwatch.StartNew();
            var uniTasks = new UniTask<UserData>[count - id + 1];
            for (int i = id; i <= count; i++)
            {
                uniTasks[i - id] = DemoDB.I.ExecuteQueryAsync<UserData>($"select * from `user` where id = {i}");  //DemoDB.I.QueryAsync<UserData>($"id = {i}");
            }
            var result = await UniTask.WhenAll(uniTasks);
            int complete = 0;
            int fail = 0;
            for (int i = 0; i < result.Length; i++)
            {
                if (result[i] != null)
                    complete++;
                else
                    fail++;
            }
            stopwatch.Stop();
            Console.WriteLine($"操作完成:{complete} 失败:{fail} 用时:{stopwatch}");
        }

        private static async UniTask TestParallel()
        {
            var stopwatch = Stopwatch.StartNew();
            await UserData.QueryAsync("id = 123");
            await RoleData.QueryListAsync("uid = 123");
            await ItemData.QueryListAsync("");
        }

        private static async UniTask AddDataTest(int count)
        {
            var stopwatch = Stopwatch.StartNew();
            var uniTasks = new UniTask<int>[count];
            for (int i = 0; i < count; i++)
            {
                var userData = new UserData
                {
                    Account = (i + 1).ToString(),
                    Password = (i + 1).ToString(),
                    Level = 1,
                    Hp = 100,
                    Mp = 100
                };
                uniTasks[i] = userData.NewRowAsync();
            }
            var result = await UniTask.WhenAll(uniTasks);
            int complete = 0;
            int fail = 0;
            for (int i = 0; i < result.Length; i++)
            {
                if (result[i] >= 1)
                    complete++;
                else
                    fail++;
            }
            stopwatch.Stop();
            Console.WriteLine($"操作完成:{complete} 失败:{fail} 用时:{stopwatch}");
        }

        private static async UniTask QueryDataTest(int id, int count)
        {
            var stopwatch = Stopwatch.StartNew();
            var uniTasks = new UniTask<UserData>[count - id + 1];
            for (int i = id; i <= count; i++)
            {
                uniTasks[i - id] = DemoDB.I.QueryAsync<UserData>($"id = {i}");
            }
            var result = await UniTask.WhenAll(uniTasks);
            int complete = 0;
            int fail = 0;
            for (int i = 0; i < result.Length; i++)
            {
                if (result[i] != null)
                    complete++;
                else
                    fail++;
            }
            stopwatch.Stop();
            Console.WriteLine($"操作完成:{complete} 失败:{fail} 用时:{stopwatch}");
        }

        private static async UniTask ModifyDataTest(int id, int count, string name, string value)
        {
            var stopwatch = Stopwatch.StartNew();
            var uniTasks = new UniTask<UserData>[count - id + 1];
            for (int i = id; i <= count; i++)
            {
                uniTasks[i - id] = DemoDB.I.QueryAsync<UserData>($"id = {i}");
            }
            var result = await UniTask.WhenAll(uniTasks);
            int complete = 0;
            int fail = 0;
            object val = null;
            switch (name)
            {
                case "level":
                    val = int.Parse(value);
                    break;
                case "name":
                    val = value;
                    break;
                case "exp":
                    val = int.Parse(value);
                    break;
                case "hp":
                    val = int.Parse(value);
                    break;
                case "mp":
                    val = int.Parse(value);
                    break;
            }
            for (int i = 0; i < result.Length; i++)
            {
                if (result[i] == null)
                {
                    fail++;
                    continue;
                }
                complete++;
                switch (name)
                {
                    case "level":
                        result[i].Level = (int)val;
                        break;
                    case "name":
                        result[i].Name = value;
                        break;
                    case "exp":
                        result[i].Exp = (int)val;
                        break;
                    case "hp":
                        result[i].Hp = (int)val;
                        break;
                    case "mp":
                        result[i].Mp = (int)val;
                        break;
                }
            }
            stopwatch.Stop();
            Console.WriteLine($"操作完成:{complete} 失败:{fail} 用时:{stopwatch}");
        }

        private static async UniTask DeleteDataTest(int id, int count)
        {
            var stopwatch = Stopwatch.StartNew();
            var uniTasks = new UniTask<UserData>[count - id + 1];
            for (int i = id; i <= count; i++)
            {
                uniTasks[i - id] = DemoDB.I.QueryAsync<UserData>($"id = {i}");
            }
            var result = await UniTask.WhenAll(uniTasks);
            var deleteTasks = new UniTask<int>[result.Length];
            for (int i = 0; i < result.Length; i++)
            {
                if (result[i] != null)
                {
                    deleteTasks[i] = result[i].DeleteAsync();
                }
            }
            var deleteResult = await UniTask.WhenAll(deleteTasks);
            int complete = 0;
            int fail = 0;
            for (int i = 0; i < deleteResult.Length; i++)
            {
                if (deleteResult[i] >= 1)
                    complete++;
                else
                    fail++;
            }
            stopwatch.Stop();
            Console.WriteLine($"操作完成:{complete} 失败:{fail} 用时:{stopwatch}");
        }
    }
}
